home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 3 / BBS in a box - Trilogy III.iso / Files / Prog / B-C / C++ FAQ Reference 1.0 / C++ FAQ Reference 1.0.rsrc / TEXT_129.txt < prev    next >
Encoding:
Text File  |  1993-06-30  |  5.8 KB  |  13 lines

  1. GROWTH OF C++: C++ is by far the most popular OOPL.  Knowing C++ is a good resume-stuffer.  But don't just use it as a better C, or you won't be using all its power.  Like any quality tool, C++ must be used the way it was designed to be used.  The number of C++ users is doubling every 7.5 to 9 months.  This exponential growth can't continue forever(!), but it is becoming a significant chunk of the programming market (it's already the dominant OOPL). 
  2.  
  3. ENCAPSULATION: For those of you who aren't on a team constructing software mega-systems, what does C++ buy you?  Here's a trivial example.  Suppose you want a 'Foible' data type.  One style of doing this in 'C' is to create a 'Foible.h' file that holds the 'public interface', then stick all the implementation into a 'Foible.c' file.  Encapsulation (hiding the details) can be achieved by making all data elements in 'Foible.c' be 'static'.  But that means you only get one 'Foible' in the entire system, which is ok if 'Foible' is a Screen or perhaps a HardDisk, but is lousy if Foible is a complex number or a line on the screen, etc.  Read on to see how it's done in 'C' vs 'C++'.
  4.  
  5. MULTIPLE INSTANCES: The 'C' solution to the above 'multiple instances' problem is to wrap all the data members in a struct (like a Pascal 'record'), then pass these structs around as if they were the 'ComplexNumber' or whatever.  But this loses encapsulation.  Other techniques can be devised which allow both multiple instances and encapsulation, however these lose on other accounts (ex: typedef'ing 'Foible' to be 'void*' loses type safety, and wrapping a 'void*' in the Foible struct loses an extra layer of indirection).  So the 'module' technique loses multiple instantiations, but the 'struct' technique loses encapsulation.  C++ allows you to combine the best of both worlds - you can have what amount to structs whose data is hidden.
  6.  
  7. INLINE FUNCTION CALLS: The 'encapsulated C' solution above requires a function call to access even trivial fields of the data type (if you allowed direct access to the struct's fields, the underlying data structure would become virtually impossible to change since too many pieces of code would *rely* on it being the 'old' way).  Function call overhead is small, but can add up.  C++ provides a solution by allowing function calls to be expanded 'inline', so you have: the (1) safety of encapsulation, (2) convenience of multiple instances, (3) speed of direct access.  Furthermore the parameter types of these inline functions are checked by the compiler, an improvement over C's #define macros. 
  8.  
  9. OVERLOADING OPERATORS: For the 'ComplexNumber' example, you want to be able to use it in an expression 'just as if' if were a builtin type like int or float. C++ allows you to overload operators, so you can tell the compiler what it means for two complex numbers to be added, subtracted, multiplied, etc.  This gives you: z0 = (z1 + z2) * z3 / z4; Furthermore you might want string1+string2 to mean string concatenation, etc.  One of the goals of C++ is to make user defined types 'look like' builtin types.  You can even have 'smart pointers', which means a pointer 'p' could actually be a user defined data type that 'points' to a disk record (for example).  'Dereferencing' such a pointer (ex: i=*p;) means ''seek to the location on disk where p 'points' and return its value''.  Also statements like p->field=27; can store things on disk, etc.  If later on you find you can fit the entire pointed-to data structure in memory, you just change the user-defined pseudo-pointer type and recompile.  All the code that used these 'pseudo pointers' doesn't need to be changed at all.
  10.  
  11. INHERITANCE: We still have just scratched the surface.  In fact, we haven't even gotten to the 'object-oriented' part yet!  Suppose you have a Stack data type with operations push, pop, etc.  Suppose you want an InvertableStack, which is 'just like' Stack except it also has an 'invert' operation.  In 'C' style, you'd have to either (1) modify the existing Stack module (trouble if 'Stack' is being used by others), or (2) copy Stack into another file and text edit that file (results in lots of code duplication, another chance to break something tricky in the Stack part of InvertableStack, and especially twice as much code to maintain).  C++ provides a much cleaner solution: inheritance. You say 'InvertableStack inherits everything from Stack, and InvertableStack adds the invert operation'.  Done.  Stack itself remains 'closed' (untouched, unmodified), and InvertableStack doesn't duplicate the code for push/pop/etc. 
  12.  
  13. POLYMORPHISM: The real power of OOP isn't just inheritance, but is the ability to pass an InvertableStack around as if it actually were a Stack.  This is 'safe' since (in C++ at least) the is-a relation follows public inheritance (ie: a InvertableStack is-a Stack that can also invert itself).  Polymorphism is easiest to understand from an example, so here's a 'classic': a graphical draw package might deal with Circles, Squares, Rectangles, general Polygons, and Lines.  All of these are Shapes.  Most of the draw package's functions need a 'Shape' parameter (as opposed to some particular kind of shape like Square). Ex: if a Shape is picked by a mouse, the Shape might get dragged across the screen and placed into a new location.  Polymorphism allows the code to work correctly even if the compiler only knows that the parameter is a 'Shape' without knowing the exact kind of Shape it is.  Furthermore suppose the 'pick_and_drag(Shape*) function just mentioned was compiled on Tuesday, and on Wednesday you decide to add the Hexagon shape.  Strange as it sounds, pick_and_drag() will still work with Hexagons, even though the Hexagon didn't even exist when pick_and_drag() was compiled!!  (it's not really 'amazing' once you understand how the C++ compiler does it -- but it's still very convenient!)